﻿Imports TyranntUserDatabase
Imports TyranntCharacterDatabase
Imports TyranntWelcomeDatabase
Imports TyranntEngine

Imports System.IO
Imports System.Security.Cryptography


Public Class WelcomeRoutines

    Private _versionMajor As Integer = 0
    Private _versionMinor As Integer = 1
    Private _versionPatch As Integer = 7

    Private udb As New UserDatabaseAccess
    Private cdb As New CharacterDatabaseAccess
    Private wdb As New WelcomeDatabaseAccess
    Private _naz As New Nabaztag
    Private _lastError As Exception

    Private Const _filesDirectory As String = "C:\Inetpub\vhosts\tyranntrpg.org\subdomains\svc\httpdocs\files"

    Public Function Hello(ByVal majorVersion As Integer, ByVal minorVersion As Integer, ByVal patchVersion As Integer) As IdentificationType
        ' Firstly add the server version into the reply message so the
        ' client can display the different version number if required
        Dim result As New IdentificationType
        result.ServerVersion = _versionMajor.ToString + "." + _versionMinor.ToString + "." + _versionPatch.ToString

        ' Now we need to check to see if the version numbers match. If not then we need to fire up
        ' the updater routines
        If majorVersion = _versionMajor And minorVersion = _versionMinor And patchVersion = _versionPatch Then
            ' we do not need to update so just carry on
            result.UpdateRequired = False
        Else
            ' an update is required so we need to get the file lists generated
            ' and not bother to carry on with this hello routine
            result.UpdateRequired = True
            result.Message = GetFilesXML()
            Return result
        End If

        Dim numUsers As Integer = udb.GetUserCount

        If numUsers < 0 Then
            result.ResultCode = numUsers
            result.Message = udb.LastError.ToString
            Return result
        ElseIf numUsers = 0 Then
            ' we need to create the admin user
            result.Message = udb.AddUser("admin", encryption.EncryptPassword("jbase99"), "Administrator", "mail@jsun.me.uk", 1)
            If result.Message <> "" Then
                result.ResultCode = -2
                Return result
            End If
        End If

        Dim numItemTypes As Integer = cdb.GetItemTypeCount
        If numItemTypes < 0 Then
            result.ResultCode = numItemTypes
            result.Message = cdb.LastError.ToString
            Return result
        ElseIf numItemTypes = 0 Then
            ' Populate Item Types
            Dim err As String
            err = cdb.AddItemType("weapon", "An item used to attack")
            If err <> "" Then
                result.ResultCode = -2
                result.Message = err
                Return result
            End If
            err = cdb.AddItemType("armor", "An item worn by charcter for defence")
            If err <> "" Then
                result.ResultCode = -2
                result.Message = err
                Return result
            End If
            err = cdb.AddItemType("healing", "An item used regain character HP")
            If err <> "" Then
                result.ResultCode = -2
                result.Message = err
                Return result
            End If
            err = cdb.AddItemType("tool", "An item required to do a task")
            If err <> "" Then
                result.ResultCode = -2
                result.Message = err
                Return result
            End If
            err = cdb.AddItemType("ammo", "An item required to user another item")
            If err <> "" Then
                result.ResultCode = -2
                result.Message = err
                Return result
            End If
        End If

        Return result
    End Function

    Private Function GetFilesXML() As String
        Return wdb.GetClientFiles()
    End Function

    Public Function AddFile(ByVal uploadStream As Stream) As String
        Dim file As FileDetails = wdb.PullPreloadFile()
        If file.Filename.Contains("[#]") = True Then
            Return file.Filename
        End If
        Return wdb.AddFile(file.Filename, uploadFile(file, uploadStream), file.FileSize)
    End Function

    Private Function uploadFile(ByVal file As FileDetails, ByVal uploadStream As Stream) As String
        Dim localFilename As String = _filesDirectory + file.Filename
        Dim sw As New FileStream(localFilename, FileMode.Create)
        Dim bw As New BinaryWriter(sw)
        Dim cnt As Long = 0
        Do
            Dim b As Integer = uploadStream.ReadByte()
            bw.Write(CByte(b))
            cnt += 1
            If cnt >= file.FileSize Then
                Exit Do
            End If
        Loop
        sw.Close()
        bw.Close()
        uploadStream.Close()
        ' now get hash
        Return GetFileHash(localFilename)
    End Function

    Public Function GetFiles(ByVal token As String) As String
        If IsAdmin(token) Then
            Return GetFilesXML()
        Else
            Return ErrorCode(-3, "GetFiles")
        End If
    End Function

    Public Function GetFile(ByVal filename As String) As Stream
        Dim fs As New StreamReader(_filesDirectory + "\" + filename)
        Return fs.BaseStream
    End Function

    Public Function PreloadFile(ByVal token As String, ByVal filename As String, ByVal size As Long) As String
        If IsAdmin(token) = False Then
            Return ErrorCode(-3, "PreloadFile")
        End If
        Return wdb.PreloadFile(filename, size)
    End Function

    Public Function DeleteFile(ByVal token As String, ByVal filename As String) As String
        If IsAdmin(token) = False Then
            Return ErrorCode(-3, "DeleteFile")
        End If
        Return wdb.DeleteFile(filename)
    End Function

    Private Function IsAdmin(ByVal token As String) As Boolean
        Dim userID As Integer = udb.GetUserIDFromToken(token)
        If userID < 0 Then
            Return False
        End If
        Dim userGroup As Integer = udb.GetUserGroup(userID)
        If userGroup = 1 Then
            Return True
        Else
            Return False
        End If
    End Function

    Public Function ErrorCode(ByVal code As Integer, ByVal func As String) As String
        Select Case code
            Case -2
                Return Failed(func)
            Case -3
                Return "[#]permissiondenied[" + func + "]"
            Case Else
                Return "[#]unknowncode[" + code.ToString + "],[" + func + "]"
        End Select
    End Function

    Public Function Failed(ByVal routine As String) As String
        _naz.SendMessage("fatal error", "Fatal error in routine " + routine + ". Exception caught!", Nabaztag.VoicesEnum.UK_Edwin)
        Return "[#]failed[" + routine + "]|" + _lastError.ToString
    End Function
End Class
